    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <ctype.h>
    #include <stdbool.h>
    #include <math.h>
    
    void  ChildProcess(int input[2], int output[2]);          /* child process prototype  */
    void  ParentProcess(int input[2], int output[2]);         /* parent process prototype */
    void  xuly(char *ch);
    void  AddChar(char *ch, char kt);
    void  AddNumber(char *ch, int n);
    void  inKt(char kt);
    void  inNumber(int n);
    bool  isOperator(char ch);
    void  errorBt();
    int   isOther(int i);

    void  main(void)
    {
         pid_t  pid;
         int input_pipe[2];
         int output_pipe[2];
         int rc, child_status;

         printf("\n\n\n________________________________________________________________________________\n");
         printf("                             DO AN NGUYEN LY HE DIEU HANH");
         printf("\n             De tai: Giao tiep cac tien trinh bang duong ong Pipe\n\n");


         rc = pipe(input_pipe);
         if(rc ==-1){
            perror("\tmain : input_pipe error");
            exit(1);
         }

         rc = pipe(output_pipe);
         if(rc ==-1){
            perror("\tmain : output_pipe error");
            exit(1);
         }

         pid = fork();
         if (pid == 0)
              ChildProcess(input_pipe, output_pipe);
         else{
              //wait( &child_status );
              ParentProcess(input_pipe, output_pipe);
         }

    }

    void  ChildProcess(int input[2], int output[2])
    {
         int    rc;
         char   ch[100] = "";
         close(input[1]);
         close(output[0]);

         rc = read(input[0], &ch, 100);
         if (rc==-1)
           {
            perror("Error");
            close(input[0]);
            close(input[1]);
            exit(1);
            }
         //Ham xu li bieu thuc vao
         xuly(ch);

         printf("\n\tKet qua ghi vao output_pipe(ChildProcess): %s\n\n", ch, strlen(ch));
         rc = write(output[1], ch, strlen(ch));
         if (rc==-1)
           {
            perror("Error");
            close(output[0]);
            close(output[1]);
            exit(1);
            }

         close(input[0]);
         close(output[1]);
    }

    void  ParentProcess(int input[2], int output[2])
    {
         int    rc;
         char   c, ch[100] = "";

         close(input[0]);
         close(output[1]);

         printf("\n\tNhap bieu thuc:    "); gets(ch);
         rc = write(input[1], ch, strlen(ch));
         if (rc==-1)
           {
            perror("Error");
            close(input[0]);
            close(input[1]);
            exit(1);
            }


         rc = read(output[0], ch, 100);
         if (rc==-1)
           {
            perror("Error");
            close(output[0]);
            close(output[1]);
            exit(1);
            }
         printf("\n\tKet qua doc ra tu output_pipe (ParentProcess): %s\n\n", ch);

         close(input[1]);
         close(output[0]);

         printf("\n________________________________________________________________________________\n\n\n");
    }

    void xuly(char *ch){
        char stack_[100] = "", kq[100] = "", tam[100]="";
        int i = 0, j = -1, k = -1, temp = 0;
        /*
        i : chi so vong lap for
        j : chi so stack
        k : chi so chuoi hau to kq
        */

        //Chuyen bieu thuc dang trung to sang hau to
        for( ; i<strlen(ch); i++){
            switch(ch[i]){
                case '+':
                    if(k<0) {
                        stack_[++j] = 'd'; //truong hop nay + la dau duong
                        break;
                    }
                    if(isOperator(ch[i-1])) {
                        while(j>=0 && (stack_[j]=='a' || stack_[j]=='d')) kq[++k] = stack_[j--];
                        stack_[++j] = 'd'; //truong hop nay + la dau duong
                        break;
                    }

                case '-':
                    if(k<0) {
                        stack_[++j] = 'a'; //truong hop nay - la dau am
                        break;
                    }
                    if(isOperator(ch[i-1])) {
                        while(j>=0 && (stack_[j]=='a' || stack_[j]=='d')) kq[++k] = stack_[j--];
                        stack_[++j] = 'a'; //truong hop nay - la dau am
                        break;
                    }
                    else{
                        while(j>=0 && (stack_[j]=='+' || stack_[j]=='-' || stack_[j]=='*' || stack_[j]=='/' || stack_[j]=='^' || stack_[j]=='a' || stack_[j]=='d') )  kq[++k] = stack_[j--];
                        stack_[++j] = ch[i];
                    }
                    break;

                case '*':
                case '/':
                    if( (k<0) || isOperator(ch[i-1]) ) {
                        errorBt();//Bieu thuc loi
                        return;
                        break;
                    }
                    else{
                        while(j>=0 && (stack_[j]=='*' || stack_[j]=='/' || stack_[j]=='^' || stack_[j]=='a' || stack_[j]=='d') ) kq[++k] = stack_[j--];
                        stack_[++j] = ch[i];
                    }
                    break;

                case '^':
                    if( k<0 || isOperator(ch[i-1]) ) {
                        errorBt();//Bieu thuc loi
                        return;
                    }
                    else{
                        while(j>=0 && (stack_[j]=='^' || stack_[j]=='a' || stack_[j]=='d'))   kq[++k] = stack_[j--];
                        stack_[++j] = ch[i];
                    }
                    break;

                case '(':
                    stack_[++j] = ch[i];
                    break;
                case ')':
                    while(j>=0 && stack_[j]!= '(') kq[++k] = stack_[j--];
                    j--;
                    break;
                default:
                    if(isdigit(ch[i]) != 0){
                        temp = temp * 10 + ch[i] - 48;
                        if(isdigit(ch[i+1])==0) {
                            kq[++k] = temp;
                            temp = 0;
                        }
                    }
                    else i = isOther(i);
            }
        }
        while(j>=0){
            kq[++k] = stack_[j--];
        }

        printf("\n\tDang trung to: %s", ch);
        printf("\n\tDang hau to: ");
        for(i = 0; i <= k; i++){
            switch(kq[i]){
                case 'd':
                    inKt('+');
                    break;
                case 'a':
                    inKt('-');
                    break;
                case '+':
                case '-':
                case '*':
                case '/':
                case '^':
                    inKt(kq[i]);
                    break;
                case 's':
                    printf("sin");
                    break;
                case 'c':
                    printf("cos");
                    break;
                default:
                    inNumber(kq[i]);
            }
        }

        //Tinh gia tri bieu thuc tu bieu thuc hau to

        /*
        i : chi so vong lap
        j : chi so stack
        temp : bien tam
        */
        i = 0; j = -1; temp = 0;
        for( ; i<= k; i++){
            switch(kq[i]){
                case 'd':
                    break;
                case 'a':
                    stack_[j]=-stack_[j];
                    break;
                case '^':
                    //stack_[j-1] = (char)pow((double)stack_[j-1], (double)stack_[j]);
                    temp = (char)mu((int)stack_[j-1], (int)stack_[j]);
                    stack_[--j] = temp;
                    break;
                case '+':
                    temp = stack_[j] + stack_[j-1];
                    stack_[--j] = temp;
                    break;
                case '-':
                    temp = stack_[j-1] - stack_[j];
                    stack_[--j] = temp;
                    break;
                case '*':
                    temp = stack_[j] * stack_[j-1];
                    stack_[--j] = temp;
                    break;
                case '/':
                    temp = stack_[j-1] / stack_[j];
                    stack_[--j] = temp;
                    break;
                default:
                    stack_[++j] = kq[i];
            }
        }
        if(j!=0) printf("\nTinh toan sai: j = %d",j);
        else printf("\n\tKet qua bieu thuc: %d", stack_[0]);

        //Bo sung ket qua sau chuoi da nhap
        AddChar(ch, '=');
        AddNumber(ch, stack_[0]);

    }

    void  AddChar(char *ch, char kt){
        ch[strlen(ch)+1] = ch[strlen(ch)];
        ch[strlen(ch)] = kt;
    }

    void AddNumber(char *ch, int n){
        char a[100];
        int i = -1;

        if(n < 0){
            n = -n;
            AddChar(ch, '-');
        }

        do{
            a[++i] = n % 10 + 48;
            n = n /10;
        }while(n);

        for( ; i >=0 ; i--){
            AddChar(ch, a[i]);
        }
    }

    void  inKt(char kt){
        printf("%c", kt);
    }

    void  inNumber(int n){
        char a[100];
        int i = 0;

        if(n < 0){
            n = -n;
            inKt('-');
        }

        do{
            a[++i] = n % 10 + 48;
            n = n /10;
        }while(n);

        for( ; i >=0 ; i--){
            inKt(a[i]);
        }
    }

bool isOperator(char ch){
    switch(ch){
        case '+':
        case '-':
        case '*':
        case '/':
        case '^':
            return true;
        default:
            return false;
    }
}

void errorBt(){
    printf("\n Bieu thuc nhap vao khong dung, khong the tinh duoc!\n\n");
    //exit(0);
}

int isOther(int i){
    printf("\n\nisOther.................\n\n");
    return i;
}

int mu(int a, int b){
    int i = 1, temp = 1;
    if(a==0) return 0;
    if(b==0) return 1;
    for( ; i<=b; i++) temp *= a;
    printf("\n\t mu(%d, %d) = %d\n", a, b, temp);
    return temp;
}








